home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / MCASM.RAR / MC_ASM.EXE / WROX_ASM / CH3 / PIANO9.ASM next >
Assembly Source File  |  1994-11-14  |  8KB  |  257 lines

  1. ;////////////////////////////////////////////////////////////
  2. ;Program 3.2. Resident Beeper.
  3. ;////////////////////////////////////////////////////////////
  4. ; PIANO9.
  5. ; This TSR program is activated by pressing
  6. ; <Ctrl> + <Right Shift>. It is protected from
  7. ; reloading twice and uninstall itself. To uninstall the
  8. ; PIANO9 from memory you should run it with the switch
  9. ; /r or /R in the command line.
  10. ; Having been activated PIANO9 produces short sounds
  11. ; of different tones for any key pressed. You can stop
  12. ; by pressing <Esc>.
  13. ; Demo program for ExpAsm Chapter3 "Fundamental System
  14. ; Programming Techniques".
  15. ;
  16.  
  17. CODE GROUP care9,init9
  18.  
  19. ; RESIDENT PART:
  20. care9 SEGMENT para
  21. ASSUME cs:code,ds:code,es:code
  22. Flag         DB 0
  23. OldInt9      DW 2 dup(?)
  24. OldInt2F     DW 2 dup(?)
  25. TSR_PSP_Addr DW ?
  26. our_TSR_Segm DW ?
  27. our_TSR_Offs DW ?
  28. ;NEW ISR FOR INTERRUPT 09h:
  29. NewInt9 PROC far
  30.             push ax
  31.             push es
  32.  
  33.             xor ax,ax
  34.             mov es,ax
  35.             test BYTE ptr es:[417h],1; Check Status
  36.                              ; Byte for <Right
  37.                              ; Shift> pressed.
  38.             jz No_Keys
  39.             test BYTE ptr es:[417h],4; Check Status
  40.                              ; Byte for <Ctrl>
  41.                              ; pressed.
  42.             jz No_Keys
  43.  
  44.             mov cs:Flag,1  ; Set Flag (<Ctrl-RShift>
  45.                        ; has been pressed).
  46. Ex_Int9:
  47.             pop es      ; Return to the standard
  48.             pop ax      ; ISR
  49.             jmp dword ptr cs:OldInt9
  50. No_Keys:
  51.             cmp cs:Flag,1  ; If Flag<>1, then return
  52.             jne Ex_Int9 ; from the procedure.
  53.  
  54.             in al,60h   ; Load the SCAN code of
  55.                        ; pressed key into AL.
  56.             cmp al,1
  57.  
  58.             jne Beep
  59.             mov cs:Flag,0  ; If ESC, then return from
  60.             jmp Ex_Int9 ; the procedure and clear
  61.                        ; Flag.
  62. Beep:
  63.             push cx
  64.             xor ah,ah   ; AL contains the SCAN code of
  65.                        ; the key pressed.
  66.             mov cl,150  ; Multiplier for SCAN code
  67.                        ; of every key.
  68.             mul cl
  69.             mov cx,ax      ; CX contains the frequency now
  70.             mov al,0B6h    ; Set channel 2 of I8253
  71.             out 43h,al
  72.             mov ax,cx
  73.             out 42h,al  ; Send lower byte of
  74.                        ; frequency.
  75.             mov al,ah   ; Send higher byte of
  76.             out 42h,al  ; frequency.
  77.  
  78.             in al,61h
  79.             mov ah,al
  80.             or al,3
  81.             out 61h,al
  82.             xor cx,cx
  83. Wait_a_little:             ; Sound generation delay.
  84.             loop Wait_a_Little
  85.  
  86.             pop cx
  87.             mov al,ah
  88.             out 61h,al
  89.  
  90.             and BYTE ptr es:[417h],11111010b
  91.             in al,61h   ; Process pressed
  92.             mov ah,al   ; keys in proper way
  93.             or al,01000000b; (instead of standard
  94.             out 61h,al  ; ISR for INT 09h)
  95.             mov al,ah
  96.             out 61h,al
  97.  
  98.             mov al,20h  ; Make the PIC to finish
  99.             out 20h,al  ; interrupt processing by
  100.                        ; sending EOI command.
  101.             pop es
  102.             pop ax
  103.             iret
  104. NewInt9 ENDP
  105.  
  106. ;NEW ISR FOR INTERRUPT 2Fh:
  107. NewInt2F PROC far
  108.             cmp ah,0E0h ; Is Number correct?
  109.             je Our_proc
  110.             jmp DWORD ptr cs:OldInt2f
  111. Our_proc:   cmp al,0    ; If install check command
  112.             jne Ex_int2f   ; then
  113.             mov al,0FFh ; set installation flag.
  114. Ex_int2f:   iret
  115. NewInt2F ENDP
  116. care9 ENDS
  117.  
  118. ;INITIALIZATION PART:
  119. init9 SEGMENT
  120. start:
  121.             jmp Go_on   ; Skip local data area.
  122.  
  123. Mess1  DB 'I really do not want to be loaded for the'
  124.        DB ' second time! <PIANO9>',10,13,'$'
  125. Mess2  DB 'PIANO9 has been successfully removed'
  126.        DB 10,13,'$'
  127. Mess3  DB 'Sorry, PIANO9 can not be removed.',10,13,'$'
  128. Mess4  DB 'Unknown switcher.',10,13,'$'
  129.  
  130. Go_on:
  131.             mov di,81h  ;Search for a slash
  132.             mov cl,es:[di-1]
  133.             mov al,'/'
  134.             repne scasb
  135.             jne Install ;If no switch in the command
  136.                        ;line then install ISRs.
  137.  
  138.             cmp byte ptr es:[di],'R';Look for 'R'or'r'
  139.             je Remove_it
  140.             cmp byte ptr es:[di],'r'
  141.             je Remove_it        ; Switch is OK.
  142.                                 ; Remove the resident
  143.             push cs
  144.             pop ds
  145.  
  146.             mov dx,cs:OFFSET Mess4 ; Warn the user about
  147.             mov ah,9              ; a wrong switch.
  148.             int 21h
  149.             jmp Exit
  150. Remove_it:
  151.             call Remove
  152.  
  153. Exit:       mov ax,4C00h; Exit the program.
  154.             int 21h
  155. Install:
  156.             push ds
  157.             push cs
  158.             pop ds
  159.  
  160.             mov ah,0E0h ;Number=0E0h
  161.             mov al,0    ;Installation Check command.
  162.             int 2Fh
  163.             cmp al,0    ;If AL<>0, then program
  164.                        ;has already installed.
  165.             jz Cont
  166.  
  167.             mov dx,cs:OFFSET Mess1 ; Tell the user that
  168.             mov ah,09h          ; resident is already
  169.             int 21h                ; installed.
  170.             jmp Exit
  171.  
  172. Cont:       mov ah,62h        ; Get PSP segment
  173.             int 21h           ; address.
  174.             mov si,es
  175.             mov es,es:[2ch]
  176.             mov ah,49h        ; Free DOS
  177.             int 21h           ; environment
  178.  
  179.             mov cs:TSR_PSP_Addr,si  ; Save PSP of the
  180.                               ; TSR part.
  181.  
  182.             mov ax,352Fh
  183.             int 21h           ; Get vector 2Fh.
  184.             mov OldInt2F,bx   ; Save vector 2Fh.
  185.             mov OldInt2F+2,es
  186.             mov dx,OFFSET NewInt2F; Set new vector 2Fh
  187.             mov ax,252Fh
  188.             int 21h
  189.  
  190.             mov ax,3509h
  191.             int 21h                 ; Get vector 09h.
  192.             mov cs:OldInt9,bx       ; Save vector 09h.
  193.             mov cs:OldInt9+2,es
  194.             mov dx,OFFSET NewInt9   
  195.             mov cs:our_TSR_Segm,ds  ; Save Segment of our ISR.
  196.             mov cs:our_TSR_Offs,dx  ; Save Offset of our ISR.
  197.                                     ; Set new vector
  198.             mov ax,2509h            ; for interrupt
  199.             int 21h                 ; 09h.
  200.  
  201.             pop dx               ; Calculate the
  202.             sub dx,init9            ; size of the
  203.             neg dx               ; resident part.
  204.             mov ax,3100h            ; Terminate and
  205.             int 21h                 ; Stay Resident.
  206.  
  207. Remove PROC near
  208.             push ds
  209.             push cs
  210.             pop ds
  211.  
  212.         mov ax,3509h    ; Get Segment and Offset
  213.             int 21h         ; of the last ISR on vector 09h.
  214.             mov cx,es:[our_TSR_Segm];Get Segment and
  215.             mov si,es:[our_TSR_Offs];Offset of our ISR
  216.             mov ax,es
  217.             cmp cx,ax       ; Compare Segment Addresses.
  218.             jnz Do_not_remove
  219.             cmp bx,si       ; Compare Offsets.
  220.             jz Free_mem
  221.  
  222. Do_not_remove:
  223.             mov dx,cs:OFFSET Mess3 ; Tell the user that
  224.             mov ah,09h          ; the resident can't be
  225.             int 21h                ; removed.
  226.             pop ds
  227.             ret         ; Don't remove the
  228.                        ; resident.
  229. Free_mem:
  230.             push ds
  231.             mov dx,es:[OldInt9]  ; Copy the
  232.             mov ds,es:[OldInt9+2]; old vector to DS:DX.
  233.             mov ax,2509h         ; Restore vector 09h
  234.             int 21h              ; using DOS service.
  235.  
  236.             mov dx,es:[OldInt2F]  ; Copy the
  237.             mov ds,es:[OldInt2F+2]; old vector to DS:DX
  238.             mov ax,252Fh          ; Restore vector 2Fh
  239.             int 21h               ; using DOS service.
  240.             pop ds
  241.  
  242.             mov es,es:[TSR_PSP_Addr]; Load ES with
  243.                             ; Segment Address of
  244.                             ; the resident part.
  245.             mov ah,49h ; Free MCB allocated for
  246.             int 21h    ; resident part.
  247.  
  248.             mov dx,cs:OFFSET Mess2  ; Tell the user that
  249.             mov ah,09h           ; resident has been
  250.             int 21h                 ; removed.
  251.             pop ds
  252.             ret
  253. Remove ENDP
  254.  
  255. init9 ENDS
  256. END start
  257.